#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

#define BUFF_SIZE 1000000

void error(const char *msg)
{
    perror(msg);
    fflush(stderr);
    fflush(stdout);
    exit(1);
}

void build_request(const char * name1, const char * name2, char * buf)
{
  bzero(buf, BUFF_SIZE);
  sprintf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
  strcat(buf, "<request xmlns=\"http://www.jpuigcerver.net/allen/xml/request.xsd\" version=\"0.1\">\n");
  strcat(buf, "<distance source=\"");
  strcat(buf, name1);
  strcat(buf, "\" target=\"");
  strcat(buf, name2); 
  strcat(buf, "\" />\n<filter>\n");
  strcat(buf, "<min>1850</min>\n");
  strcat(buf, "<max>2050</max>\n");
  strcat(buf, "<suspended>true</suspended>\n");
  strcat(buf, "<medias><media>All</media></medias>\n");
  strcat(buf, "<genres><genre>All</genre></genres>\n");
  strcat(buf, "<works><work>All</work></works>\n");
  strcat(buf, "</filter>\n");
  strcat(buf, "</request>");
}

int main(int argc, char *argv[])
{
  char buffer[BUFF_SIZE];
  char name1[256], name2[256];
  int sockfd, portno, n;
  size_t read_bytes;

  struct sockaddr_in serv_addr;
  struct hostent *server; 
  
  if (argc < 3) {
    fprintf(stderr,"usage %s hostname port\n", argv[0]);
    exit(0);
  }
  portno = atoi(argv[2]);

  server = gethostbyname(argv[1]);
  if (server == NULL) {
    fprintf(stderr,"ERROR, no such host\n");
    exit(0);
  }
  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  bcopy((char *)server->h_addr, 
	(char *)&serv_addr.sin_addr.s_addr,
	server->h_length);
  serv_addr.sin_port = htons(portno);
  
  while(1) {
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
      error("ERROR opening socket");
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
      error("ERROR connecting");

    printf("Name 1: "); bzero(name1, 256); fgets(name1, 255, stdin);
    printf("Name 2: "); bzero(name2, 256); fgets(name2, 255, stdin);
    name1[strlen(name1)-1] = '\0';
    name2[strlen(name2)-1] = '\0';

    if ( !strcmp(name1, "") || !strcmp(name2, "") ) break;
    
    /* send request */
    build_request(name1, name2, buffer);    
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
      error("ERROR writing to socket");
    printf("Request:\n==========\n%s\n==========\n",buffer);
    
    /* get response */
    memset(buffer, 0x00, BUFF_SIZE);
    read_bytes = 0;
    do {
      n = read(sockfd, buffer+(read_bytes++), 1);
    } while ( n > 0 );

    printf("Response:\n==========\n%s\n==========\n",buffer);
    shutdown(sockfd, SHUT_RDWR);
    close(sockfd);
  } 
  
  return 0;
}
